#include "flight.h"
#include "list.h"
// 浏览航班信息功能：该功能实现了将系统中所有的航班信息全部输出到屏幕上的功能。
void showFlightNode(FlightNode *head)
{
    if (head->next == head)
    {
        printf("航班信息为空!");
        return;
    }
    FlightNode *p = head->next;
    printf("+---------------------------------------------------------------------------------------+\n");
    printf("|                                      航班信息表                                       |\n");
    while (p != head)
    {
        printf("|  起点站:%s\t\t", p->data.start_city);
        printf("终点站:%s\t\t", p->data.arrive_city);
        printf("总票数:%d\t", p->data.max_num);
        printf("航班号:%s\t", p->data.flight_num);
        printf("班次:%d  |\n", p->data.id);
        printf("|  %s\t", p->data.start_time);
        printf("%s\t", p->data.arrive_time);
        printf("余票:%3d    ", p->data.left_num);
        printf("票价:%4d    ", p->data.value);
        printf("机型:%s  |\n", p->data.flight_type);
        puts("|                                                                                       |");
        p = p->next;
    }
    printf("+---------------------------------------------------------------------------------------+\n");
}
// 增加航班信息功能：该功能实现了增加详细航班信息后，添加该信息到系统中。
void addFlightInformation(FlightNode *head)
{
    FlightData *data = malloc(sizeof(FlightData));
    if (NULL == data)
    {
        printf("添加失败！\n");
        return;
    }
    printf("请输入航班班次:");
    scanf("%d", &data->id);
    printf("请输入航班代号:");
    scanf("%s", data->flight_num);
    printf("请输入飞机机型:");
    scanf("%s", data->flight_type);
    printf("请输入航班起点站:");
    scanf("%s", data->start_city);
    printf("请输入航班出发时间:(按照此格式输入:YYYY-MM-DD_HH:MM)");
    scanf("%s", data->start_time);
    printf("请输入航班终点站:");
    scanf("%s", data->arrive_city);
    printf("请输入航班到达时间:(按照此格式输入:YYYY-MM-DD_HH:MM)");
    scanf("%s", data->arrive_time);
    printf("请输入航班票价:");
    scanf("%d", &data->value);
    printf("请输入航班总票数:");
    scanf("%d", &data->max_num);
    printf("请输入航班余票:");
    scanf("%d", &data->left_num);
    addFlightNode(head, data);
    printf("添加成功！\n");
}
// 查询航班路线功能：该功能包含两种选择，一是根据用户选择的班次信息输出对应的航班信息；二是根据用户输入的终点站，输出所有到达该站点的航班信息。（根据部分信息查询全部信息）      已检验
void searchFlightInformation(FlightNode *head)
{
    int flag_s = 0, id = 0;
    char arrive_city[20];
    FlightNode *p = head->next;
    printf("请选择通过哪种方式查询航班信息:(1)航班班次 (2)航班终点站\n");
    scanf("%d", &flag_s);
    if (flag_s == 1)
    {
        printf("请输入航班班次:\n");
        scanf("%d", &id);
        while (p != head)
        {
            if (p->data.id == id)
            {
                printf("起点站:%s\t\t", p->data.start_city);
                printf("终点站:%s\t\t", p->data.arrive_city);
                printf("总票数:%d\t", p->data.max_num);
                printf("航班号:%s\t", p->data.flight_num);
                printf("班次:%d\n", p->data.id);

                printf("%s\t", p->data.start_time);
                printf("%s\t", p->data.arrive_time);
                printf("余票:%d\t", p->data.left_num);
                printf("票价:%d\t", p->data.value);
                printf("机型:%s\n", p->data.flight_type);
                return;
            }
            p = p->next;
        }
        printf("未找到对应班次航班！");
    }
    else if (flag_s == 2)
    {

        printf("请输入航班终点站:\n");
        scanf("%s", arrive_city);
        while (p != head)
        {
            if (!strcmp(p->data.arrive_city, arrive_city))
            {
                printf("起点站:%s\t\t", p->data.start_city);
                printf("终点站:%s\t\t", p->data.arrive_city);
                printf("总票数:%d\t", p->data.max_num);
                printf("航班号:%s\t", p->data.flight_num);
                printf("班次:%d\n", p->data.id);

                printf("%s\t", p->data.start_time);
                printf("%s\t", p->data.arrive_time);
                printf("余票:%d\t", p->data.left_num);
                printf("票价:%d\t", p->data.value);
                printf("机型:%s\n", p->data.flight_type);
                return;
            }
            p = p->next;
        }
        printf("未找到对应终点站航班！");
    }
}
// 修改航班信息功能：该功能可以修改指定航班的某项信息，以实时更新航班信息。
void modifyFlightInformation(FlightNode *head)
{
    int flag_m = 0, id = 0;
    FlightNode *p = head->next;
    showFlightNode(head);
    printf("请输入要修改信息的航班班次:(回车结束输入)");
    scanf("%d", &id);
    system("clear");
    while (p != head)
    {
        if (p->data.id == id)
        {

            printf("+--------------------------------------------------------+\n");
            printf("|                   航班管理系统                         |\n");
            printf("|                                                        |\n");
            printf("|  (1)航班班次  (2)航班代号  (3)飞机机型  (4)航班起点站  |\n");
            printf("|                                                        |\n");
            printf("|  (5)航班出发时间     (6)航班终点站    (7)航班到达时间  |\n");
            printf("|                                                        |\n");
            printf("|  (8)航班票价       (9)航班总票数        (10)航班余票   |\n");
            printf("+--------------------------------------------------------+\n");
            // printf("(1)航班班次 (2)航班代号 (3)飞机机型 (4)航班起点站 (5)航班出发时间 (6)航班终点站 (7)航班到达时间 (8)航班票价 (9)航班总票数 (10)航班余票\n");
            printf("请选择要修改的航班信息:\n");
            scanf("%d", &flag_m);
            switch (flag_m)
            {
            case 1:
                printf("请输入航班班次:");
                scanf("%d", &p->data.id);
                break;
            case 2:
                printf("请输入航班代号:");
                scanf("%s", p->data.flight_num);
                break;
            case 3:
                printf("请输入飞机机型:");
                scanf("%s", p->data.flight_type);
                break;
            case 4:
                printf("请输入航班起点站:");
                scanf("%s", p->data.start_city);
                break;
            case 5:
                printf("请输入航班出发时间:(按照此格式输入:YYYY-MM-DD_HH:MM)");
                scanf("%s", p->data.start_time);
                break;
            case 6:
                printf("请输入航班终点站:");
                scanf("%s", p->data.arrive_city);
                break;
            case 7:
                printf("请输入航班到达时间:(按照此格式输入:YYYY-MM-DD_HH:MM)");
                scanf("%s", p->data.arrive_time);
                break;
            case 8:
                printf("请输入航班票价:");
                scanf("%d", &p->data.value);
                break;
            case 9:
                printf("请输入航班总票数:");
                scanf("%d", &p->data.max_num);
                break;
            case 10:
                printf("请输入航班余票:");
                scanf("%d", &p->data.left_num);
                break;
            }
            printf("修改成功！\n");
            return;
        }
        p = p->next;
    }
    printf("未找到该班次航班\n");
}
// 删除航班信息功能：该功能实现了可以删除某项航班信息的功能。
void deleteFlightInformation(FlightNode *head)
{
    int id = 0;
    FlightNode *p = head->next;
    showFlightNode(head);
    printf("请输入要删除的航班班次:\n");
    scanf("%d", &id);
    while (p != head)
    {
        if (p->data.id == id)
        {
            if (p == head->next)
            {
                head->next = p->next;
                p->next->prev = p->prev;
                free(p);
                head->len--;
            }
            else
            {
                p->prev->next = p->next;
                p->next->prev = p->prev;
                free(p);
                head->len--;
            }
            printf("删除成功！\n");
            return;
        }
        p = p->next;
    }
    printf("未找到该班次航班\n");
}
// 排序航班信息功能：该功能实现了根据起飞时间进行排序功能。
void sortFlightInformation(FlightNode *head)
{
    // 基于选择排序的指针操作形式
    FlightNode *p = head->next;
    FlightNode *q = head->next;
    FlightData temp = {0};

    while (p != head)
    {
        q = p->next;
        while (q != head)
        {
            if (convertTimeType(p->data.start_time) > convertTimeType(q->data.start_time))
            {
                temp = (*p).data;
                (*p).data = (*q).data;
                (*q).data = temp;
            }
            q = q->next;
        }
        p = p->next;
    }
    printf("航班按时间正序排列如下\n");
    showFlightNode(head);
}
// 购票功能：该功能实现了当用户指定日期与班次信息时，相应地为该航班增加售出记录，但是如果该航班已经起飞或者该航班的机票已经售空，用户将购买失败，系统会给予用户相应的提示。
void buyTicket(FlightNode *head, UserData *user) //
{
    int num = 0;
    char date[30] = "";
    char number[30] = "";
    // 从链表的第一个节点开始遍历
    FlightNode *p = head->next;
    // 展示所有航班信息
    showFlightNode(head);
    printf("请输入要购买的航班出发时间:(按照此格式输入: YYYY-MM-DD_HH:MM)\n");
    scanf("%s", date);
    printf("请输入要购买的航班号\n");
    scanf("%s", number);
    while (p != head)
    {
        // 检查输入的日期和航班是否与任一航班的匹配
        if (!strcmp(p->data.start_time, date) && !strcmp(p->data.flight_num, number))
        {
            // 检查所选航班是否已售罄
            if (p->data.left_num == 0)
            {
                printf("该航班的机票已经售空，无法购买\n");
                return;
            }
            else
            {
                printf("请输入要购买的机票数量:\n");
                scanf("%d", &num);
                // 检查所选航班是否有足够的余票
                if (num > p->data.left_num)
                {
                    printf("余票不足，无法购买\n");
                    return;
                }
                else if (user->ticket_num + num > 5)
                {
                    printf("每人最多限制购票五张，无法购买\n");
                    return;
                }
                else
                {
                    // 成功购买机票的操作
                    for (int i = user->ticket_num; i < user->ticket_num + num; i++)
                    {
                        user->ticket[i] = p->data;
                    }
                    user->ticket_num += num;
                    p->data.left_num -= num;
                    printf("购买成功！\n");
                    return;
                }
            }
        }
        p = p->next;
    }
    printf("无此航班信息\n");
}
// 退票功能：该功能实现了当用户指定日期与班次信息时，相应地为该航班增加售出记录，但是如果该航班已经起飞或者该航班的机票已经售空，用户将购买失败，系统会给予用户相应的提示。
void refundTicket(FlightNode *head, UserData *user) //
{
    // 用于存储用户要退票的数量，日期和航班号
    int num = 0;
    char date[20] = "";
    char number[20] = "";
    FlightNode *p = head->next;
    // 显示所有航班信息
    if (user->ticket_num == 0)
    {
        printf("此用户下无购票记录\n");
        return;
    }
    else
    {
        printf("你已购买的航票信息如下：\n");
    }
    for (int i = 0; i < user->ticket_num; i++)
    {
        printf("起点站:%s\t\t", user->ticket[i].start_city);
        printf("终点站:%s\t\t", user->ticket[i].arrive_city);
        printf("总票数:%d\t", user->ticket[i].max_num);
        printf("航班号:%s\t", user->ticket[i].flight_num);
        printf("班次:%d\n", user->ticket[i].id);
        printf("%s\t", user->ticket[i].start_time);
        printf("%s\t", user->ticket[i].arrive_time);
        printf("余票:%3d    ", user->ticket[i].left_num);
        printf("票价:%4d    ", user->ticket[i].value);
        printf("机型:%s\n", user->ticket[i].flight_type);
        puts("");
    }
    printf("请输入要退票的航班起飞时间(按照此格式输入: YYYY-MM-DD_HH:MM)");
    scanf(" %s", date);
    printf("请输入要退票的航班号:");
    scanf(" %s", number);
    // 遍历航班信息链表
    while (p != head)
    {
        // 查找与输入信息匹配的航班
        if (!strcmp(p->data.flight_num, number) && !strcmp(p->data.start_time, date))
        {
            // 在用户机票信息中查找对应的机票
            for (int i = 0; i < user->ticket_num; i++)
            {
                if (!strcmp(user->ticket[i].flight_num, number) && (!strcmp(user->ticket[i].start_time, date)))
                {
                    printf("请输入要退票的数量:");
                    scanf("%d", &num);
                    // 判断退票数量是否合法
                    if (num <= user->ticket_num)
                    {
                        // 更新用户剩余票数
                        user->ticket_num -= num;
                        // 调整用户机票信息数组，将退票部分移至数组末尾
                        for (int j = 0; j < user->ticket_num; j++)
                        {
                            user->ticket[j] = user->ticket[j + num];
                        }
                        // 更新航班剩余票数
                        p->data.left_num += num;
                        // printf("%d\n", p->data.left_num);
                        printf("退票成功！\n");
                        return;
                    }
                }
            }
        }
        p = p->next;
    }
    printf("请检查机票信息,退票失败！");
}
// 时间转换函数：将YYYY-MM-DD_HH:MM:SS格式的时间转换为秒数
long long convertTimeType(char *time)
{
    int year, month, day, hour, minute;
    sscanf(time, "%d-%d-%d_%d:%d", &year, &month, &day, &hour, &minute);
    return ((year - 1970) * 365 * 24 * 60 * 60 + (month - 1) * 30 * 24 * 60 * 60 + day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + 3 * 24 * 60 * 60);
}
